package com.xzc.one.common.pay.alipay;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * 支付宝支付工具
 */
@Service
public class AliWapPayTools {
    private final String SERVERURL = "https://openapi.alipay.com/gateway.do";
    private final String FORMAT = "json";
    private final String CHARSET = "UTF-8";
    private final String SIGNTYPE = "RSA2";
    private String APPID;
    private String PRIVATEKEY;
    private String PUBLICKEY;
    private AlipayClient alipayClient = null;

    public AliWapPayTools() throws Exception {
        String path = System.getProperty("user.dir") + "/aliPay.properties";

        if (new File(path).exists()) {
            FileInputStream in = new FileInputStream(path);
            Properties pro = new Properties();
            pro.load(in);
            in.close();
            APPID = pro.get("appID") + "";
            PRIVATEKEY = pro.get("PRIVATEKEY") + "";
            PUBLICKEY = pro.get("PUBLICKEY") + "";
            alipayClient = new DefaultAlipayClient(SERVERURL, APPID, PRIVATEKEY, FORMAT, CHARSET, PUBLICKEY, SIGNTYPE);
        }
    }

    /**
     * 支付宝下单
     *
     * @param body
     * @param orNo
     * @param amount
     * @param notify_url
     * @throws Exception
     */
    public String creatWapOrder(String body, String orNo, int amount, String notify_url, String return_url) throws Exception {
        String strAmount = String.format("%.2f", new BigDecimal(amount).divide(new BigDecimal(100)));
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(body);
        model.setSubject(body);
        model.setOutTradeNo(orNo);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(strAmount);
        model.setProductCode("QUICK_WAP_PAY");//h5支付类型
        request.setBizModel(model);
        request.setReturnUrl(return_url);
        request.setNotifyUrl(notify_url);
        AlipayTradeWapPayResponse response = alipayClient.sdkExecute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return response.getBody();
        } else {
            System.out.println("调用失败");
        }
        return null;
    }

    /**
     * 支付回调解密
     *
     * @param requestParams
     * @return
     * @throws Exception
     */
    public boolean checkCallBack(Map<String, String[]> requestParams) throws Exception {
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        for (String name : requestParams.keySet()) {
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
//切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        return AlipaySignature.rsaCheckV1(params, PUBLICKEY, "UTF-8", "RSA2");
    }

    /**
     * 取消订单（已支付的订单则退还金额）
     *
     * @param orno 订单编号
     * @return
     */
    public boolean cancelOrder(String orno) throws Exception {
        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        request.setBizContent("{" + "\"out_trade_no\":\"" + orno + "\"}");
        AlipayTradeCancelResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;
        } else {
            System.out.println("调用失败");
        }
        return false;
    }

    /**
     * 订单退款（全额退款、部分退款）
     *
     * @param orno     订单编号
     * @param amount   订单金额（分）
     * @param reason   退款原因
     * @param refondNo 退款单号
     * @return
     * @throws Exception
     */
    public boolean refound(String orno, Integer amount, String reason, String refondNo) throws Exception {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        String strAmount = String.format("%.2f", new BigDecimal(amount).divide(new BigDecimal(100)));
        reason = (reason == null || reason.isEmpty() ? "正常退款" : reason);
        request.setBizContent("{" +
                "\"out_trade_no\":\"" + orno + "\"," +
                //"\"trade_no\":\"2014112611001004680073956707\"," +
                "\"refund_amount\":" + strAmount + "," +
                "\"refund_reason\":\"" + reason + "\"," +
                "\"out_request_no\":\"" + refondNo + "\"" +
                //"\"operator_id\":\"OP001\"," +
                //"\"store_id\":\"NJ_S_001\"," +
                //"\"terminal_id\":\"NJ_T_001\"" +
                "  }");
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;
        } else {
            System.out.println("调用失败");
        }
        return false;
    }

    /**
     * 支付结果查询
     *
     * @param orno
     * @return
     * @throws Exception
     */
    public String queryOrder(String orno) throws Exception {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent("{" +
                "\"out_trade_no\":\"" + orno + "\"" +
                //"\"trade_no\":\"2014112611001004680073956707\"" +
                "}");
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return response.getTradeStatus();
        } else {
            System.out.println("调用失败");
        }
        return null;
    }

    public enum AliPayResult {
        WAIT_BUYER_PAY("交易创建，等待买家付款", "WAIT_BUYER_PAY"),
        TRADE_CLOSED("未付款交易超时关闭，或支付完成后全额退款", "TRADE_CLOSED"),//退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。$n为下标，从0开始编号。
        TRADE_SUCCESS("交易支付成功", "TRADE_SUCCESS"),
        TRADE_FINISHED("交易结束，不可退款", "TRADE_FINISHED");
        private String name;
        private String value;

        AliPayResult(String name, String value) {
            this.name = name;
            this.value = value;
        }

        public String getName() {
            return name;
        }

        public String getValue() {
            return value;
        }
    }

}
